home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / stdlib / RCS / atof.c,v < prev    next >
Encoding:
Text File  |  1991-12-03  |  6.4 KB  |  304 lines

  1. head     1.2;
  2. branch   ;
  3. access   ;
  4. symbols  sprited:1.2.1;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.2
  10. date     89.03.22.00.46.56;  author rab;  state Exp;
  11. branches 1.2.1.1;
  12. next     1.1;
  13.  
  14. 1.1
  15. date     88.04.28.17.20.19;  author ouster;  state Exp;
  16. branches ;
  17. next     ;
  18.  
  19. 1.2.1.1
  20. date     91.12.02.21.57.29;  author kupfer;  state Exp;
  21. branches ;
  22. next     ;
  23.  
  24.  
  25. desc
  26. @@
  27.  
  28.  
  29. 1.2
  30. log
  31. @*** empty log message ***
  32. @
  33. text
  34. @/* 
  35.  * atof.c --
  36.  *
  37.  *    Source code for the "atof" library procedure.
  38.  *
  39.  * Copyright 1988 Regents of the University of California
  40.  * Permission to use, copy, modify, and distribute this
  41.  * software and its documentation for any purpose and without
  42.  * fee is hereby granted, provided that the above copyright
  43.  * notice appear in all copies.  The University of California
  44.  * makes no representations about the suitability of this
  45.  * software for any purpose.  It is provided "as is" without
  46.  * express or implied warranty.
  47.  */
  48.  
  49. #ifndef lint
  50. static char rcsid[] = "$Header: /sprite/src/lib/c/stdlib/RCS/atof.c,v 1.1 88/04/28 17:20:19 ouster Exp Locker: rab $ SPRITE (Berkeley)";
  51. #endif /* not lint */
  52.  
  53. #include <stdlib.h>
  54. #include <ctype.h>
  55.  
  56. #ifndef TRUE
  57. #define TRUE 1
  58. #define FALSE 0
  59. #endif
  60.  
  61. static int maxExponent = 511;    /* Largest possible base 10 exponent.  Any
  62.                  * exponent larger than this will already
  63.                  * produce underflow or overflow, so there's
  64.                  * no need to worry about additional digits.
  65.                  */
  66. static double powersOf10[] = {    /* Table giving binary powers of 10.  Entry */
  67.     10.,            /* is 10^2^i.  Used to convert decimal */
  68.     100.,            /* exponents into floating-point numbers. */
  69.     1.0e4,
  70.     1.0e8,
  71.     1.0e16,
  72.     1.0e32,
  73.     1.0e64,
  74.     1.0e128,
  75.     1.0e256
  76. };
  77.  
  78. /*
  79.  *----------------------------------------------------------------------
  80.  *
  81.  * atof --
  82.  *
  83.  *    This procedure converts a floating-point number from an ASCII
  84.  *    decimal representation to internal double-precision format.
  85.  *
  86.  * Results:
  87.  *    The return value is the floating-point equivalent of string.
  88.  *    If a terminating character is found before any floating-point
  89.  *    digits, then zero is returned.
  90.  *
  91.  * Side effects:
  92.  *    None.
  93.  *
  94.  *----------------------------------------------------------------------
  95.  */
  96.  
  97. double
  98. atof(string)
  99.     char *string;        /* A decimal ASCII floating-point number,
  100.                  * optionally preceded by white space.
  101.                  * Must have form "-I.FE-X", where I is the
  102.                  * integer part of the mantissa, F is the
  103.                  * fractional part of the mantissa, and X
  104.                  * is the exponent.  Either of the signs
  105.                  * may be "+", "-", or omitted.  Either I
  106.                  * or F may be omitted, or both.  The decimal
  107.                  * point isn't necessary unless F is present.
  108.                  * The "E" may actually be an "e".  E and X
  109.                  * may both be omitted (but not just one).
  110.                  */
  111. {
  112.     int sign, expSign = FALSE;
  113.     double fraction, dblExp, *d;
  114.     register char *p, c;
  115.     int exp = 0;        /* Exponent read from "EX" field. */
  116.     int fracExp = 0;        /* Exponent that derives from the fractional
  117.                  * part.  Under normal circumstatnces, it is
  118.                  * the negative of the number of digits in F.
  119.                  * However, if I is very long, the last digits
  120.                  * of I get dropped (otherwise a long I with a
  121.                  * large negative exponent could cause an
  122.                  * unnecessary overflow on I alone).  In this
  123.                  * case, fracExp is incremented one for each
  124.                  * dropped digit.
  125.                  */
  126.     int mantSize;        /* Number of digits in mantissa. */
  127.     int decPt;            /* Number of mantissa digits BEFORE decimal
  128.                  * point.
  129.                  */
  130.     char *pExp;            /* Temporarily holds location of exponent
  131.                  * in string.
  132.                  */
  133.  
  134.     /*
  135.      * Strip off leading blanks and check for a sign.
  136.      */
  137.  
  138.     p = string;
  139.     while (isspace(*p)) {
  140.     p += 1;
  141.     }
  142.     if (*p == '-') {
  143.     sign =     TRUE;
  144.     p += 1;
  145.     } else {
  146.     if (*p == '+') {
  147.         p += 1;
  148.     }
  149.     sign = FALSE;
  150.     }
  151.  
  152.     /*
  153.      * Count the number of digits in the mantissa (including the decimal
  154.      * point), and also locate the decimal point.
  155.      */
  156.  
  157.     decPt = -1;
  158.     for (mantSize = 0; ; mantSize += 1)
  159.     {
  160.     c = *p;
  161.     if (!isdigit(c)) {
  162.         if ((c != '.') || (decPt >= 0)) {
  163.         break;
  164.         }
  165.         decPt = mantSize;
  166.     }
  167.     p += 1;
  168.     }
  169.  
  170.     /*
  171.      * Now suck up the digits in the mantissa.  Use two integers to
  172.      * collect 9 digits each (this is faster than using floating-point).
  173.      * If the mantissa has more than 18 digits, ignore the extras, since
  174.      * they can't affect the value anyway.
  175.      */
  176.     
  177.     pExp  = p;
  178.     p -= mantSize;
  179.     if (decPt < 0) {
  180.     decPt = mantSize;
  181.     } else {
  182.     mantSize -= 1;            /* One of the digits was the point. */
  183.     }
  184.     if (mantSize > 18) {
  185.     fracExp = decPt - 18;
  186.     mantSize = 18;
  187.     } else {
  188.     fracExp = decPt - mantSize;
  189.     }
  190.     if (mantSize == 0) {
  191.     return 0.0;
  192.     } else {
  193.     int frac1, frac2;
  194.     frac1 = 0;
  195.     for ( ; mantSize > 9; mantSize -= 1)
  196.     {
  197.         c = *p;
  198.         p += 1;
  199.         if (c == '.') {
  200.         c = *p;
  201.         p += 1;
  202.         }
  203.         frac1 = 10*frac1 + (c - '0');
  204.     }
  205.     frac2 = 0;
  206.     for (; mantSize > 0; mantSize -= 1)
  207.     {
  208.         c = *p;
  209.         p += 1;
  210.         if (c == '.') {
  211.         c = *p;
  212.         p += 1;
  213.         }
  214.         frac2 = 10*frac2 + (c - '0');
  215.     }
  216.     fraction = (1.0e9 * frac1) + frac2;
  217.     }
  218.  
  219.     /*
  220.      * Skim off the exponent.
  221.      */
  222.  
  223.     p = pExp;
  224.     if ((*p == 'E') || (*p == 'e')) {
  225.     p += 1;
  226.     if (*p == '-') {
  227.         expSign = TRUE;
  228.         p += 1;
  229.     } else {
  230.         if (*p == '+') {
  231.         p += 1;
  232.         }
  233.         expSign = FALSE;
  234.     }
  235.     while (isdigit(*p)) {
  236.         exp = exp * 10 + (*p - '0');
  237.         p += 1;
  238.     }
  239.     }
  240.     if (expSign) {
  241.     exp = fracExp - exp;
  242.     } else {
  243.     exp = fracExp + exp;
  244.     }
  245.  
  246.     /*
  247.      * Generate a floating-point number that represents the exponent.
  248.      * Do this by processing the exponent one bit at a time to combine
  249.      * many powers of 2 of 10. Then combine the exponent with the
  250.      * fraction.
  251.      */
  252.  
  253.     if (exp < 0) {
  254.     expSign = TRUE;
  255.     exp = -exp;
  256.     } else {
  257.     expSign = FALSE;
  258.     }
  259.     if (exp > maxExponent) {
  260.     exp = maxExponent;
  261.     }
  262.     dblExp = 1.0;
  263.     for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
  264.     if (exp & 01) {
  265.         dblExp *= *d;
  266.     }
  267.     }
  268.     if (expSign) {
  269.     fraction /= dblExp;
  270.     } else {
  271.     fraction *= dblExp;
  272.     }
  273.  
  274.     if (sign) {
  275.     return -fraction;
  276.     }
  277.     return fraction;
  278. }
  279. @
  280.  
  281.  
  282. 1.2.1.1
  283. log
  284. @Initial branch for Sprite server.
  285. @
  286. text
  287. @d17 1
  288. a17 1
  289. static char rcsid[] = "$Header: /sprite/src/lib/c/stdlib/RCS/atof.c,v 1.2 89/03/22 00:46:56 rab Exp $ SPRITE (Berkeley)";
  290. @
  291.  
  292.  
  293. 1.1
  294. log
  295. @Initial revision
  296. @
  297. text
  298. @d17 2
  299. a18 2
  300. static char rcsid[] = "$Header: proto.c,v 1.2 88/03/11 08:39:08 ouster Exp $ SPRITE (Berkeley)";
  301. #endif not lint
  302. d20 1
  303. @
  304.